package com.hww.v2_mtfsdk.utils.camera;

import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.TextureView;

import com.hww.common.util.LogUtils;

import java.util.List;

/**
 * @author hww
 * @date 2020/11/5
 * email：
 * description：
 */
public class Camera1TextureView extends TextureView {

    private CameraCallBack cameraCallBack;
    private SurfaceTexture surfaceTexture;
    /**
     * 摄像头对象
     */
    private Camera camera;
    /**
     * 摄像ID
     */
    private int cameraID = Camera.CameraInfo.CAMERA_FACING_BACK;
    /**
     * 摄像预览界面旋转角度
     */
    private int orientation = 90;
    /**
     * 摄像头预览的宽
     */
    private int previewWidth = 640;
    /**
     * 摄像头预览的高
     */
    private int previewHeight = 480;

    private Context context;

    public Camera1TextureView(Context context) {
        super(context);
        this.context = context;
        this.setSurfaceTextureListener(listener);
    }

    public Camera1TextureView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        this.setSurfaceTextureListener(listener);
    }


    /**
     * 初始化相关参数
     *
     * @param cameraID
     * @param orientation
     * @param cameraCallBack
     */
    public void initCameraParams(int cameraID, int orientation, CameraCallBack cameraCallBack) {
        this.cameraID = cameraID;
        this.orientation = orientation;
        this.cameraCallBack = cameraCallBack;

        this.setSurfaceTextureListener(listener);
    }

    /**
     * 打开摄像头并显示
     */
    public void startPreview() {
        synchronized (this) {
            if (null != camera) {
                setCameraStatusFalse("camera object is not null");
                return;
            }
            try {
                camera = Camera.open(cameraID);
                Camera.Parameters parameters = camera.getParameters();
                List<Camera.Size> previewSize = parameters.getSupportedPreviewSizes();
                if (!previewSizeStatus(previewSize)) {
                    return;
                }
                parameters.setPreviewSize(previewWidth, previewHeight);
//            if (MyApplication.dCamera.openFlash) {
//                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
//            }
//            List<String> supportedFocusModes = parameters.getSupportedFocusModes();
//            for (String mode : supportedFocusModes) {
//                Log.e("hwwFace", "focus mode : " + mode);
//            }

//            List<String> supportedSceneModes = parameters.getSupportedSceneModes();
//            for (String mode : supportedSceneModes) {
//                Log.e("hwwFace", "mode : " + mode);
//            }
                camera.setParameters(parameters);
                try {
                    if ("ISCAN500F".equals(Build.MODEL)) {
                        parameters.setSceneMode("sports");
                        parameters.setFocusMode("infinity");
                        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
                        camera.setParameters(parameters);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                if (null != cameraCallBackBuffer) {
                    cameraCallBackBuffer = null;
                }
                bufferCameraCallbackSize = previewHeight * previewWidth * ImageFormat.getBitsPerPixel(parameters.getPreviewFormat()) / 8;
                cameraCallBackBuffer = new byte[bufferCameraCallbackSize];
                camera.addCallbackBuffer(cameraCallBackBuffer);

                camera.setDisplayOrientation(orientation);
                camera.setPreviewCallbackWithBuffer(previewCallback);
                Log.e("hwwFace", "--------------------------------------setPreviewCallbackWithBuffer");
                LogUtils.file("Camera1TextureView", "--------------------------------------  " + String.format("surfaceText=%s", (null == surfaceTexture ? "空" : "非空")));
                camera.setPreviewTexture(surfaceTexture);
                LogUtils.file("Camera1TextureView", "--------------------------------------setPreviewDisplay");
                camera.startPreview();
                LogUtils.file("Camera1TextureView", "--------------------------------------startPreview");
                if (null != cameraCallBack) {
                    cameraCallBack.cameraStatus(true, String.format("openCamera success  id=%s   disPlay=%s", cameraID, orientation));
                }

            } catch (Exception e) {
                setCameraStatusFalse("Error: " + e.getMessage());
                LogUtils.file("Camera1TextureView", "Exception: " + e.toString());
                e.printStackTrace();
            }
        }
    }

    /**
     * 配置摄像头参数宽高
     *
     * @param width
     * @param height
     */
    public void setPreViewParams(int width, int height) {
        this.previewWidth = width;
        this.previewHeight = height;
    }

    private boolean previewSizeStatus(List<Camera.Size> previewSize) {
        for (Camera.Size size : previewSize) {
            if (previewWidth == size.width && previewHeight == size.height) {
                return true;
            }
        }
        setCameraStatusFalse(String.format("parameter error: Size  width:%s height:%s", previewWidth, previewHeight));
        return false;
    }

    /**
     * 关闭显示，同时释放摄像头
     */
    public void stopPreview() {
        synchronized (this) {
            LogUtils.file("Camera1TextureView", "----------------------------------stopPreview  start");
            if (null != camera) {
                camera.setPreviewCallbackWithBuffer(null);
                camera.setPreviewCallback(null);
                camera.stopPreview();
                /*camera.unlock();*/
                camera.release();
                cameraCallBackBuffer = null;
                camera = null;
                LogUtils.file("Camera1TextureView", "----------------------------------stopPreview  end");
            }
        }
    }

    SurfaceTextureListener listener = new SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            LogUtils.file("Camera1TextureView", "----------------------------------onSurfaceTextureAvailable   "
                    + String.format("surface=%s    camera=%s", (null == surface ? "空" : "非空"), (null == camera ? "空" : "非空")));
            if (null != surface) {
                surfaceTexture = surface;
            }
            if (null != camera) {
                try {
                    camera.setPreviewTexture(surface);
                    camera.startPreview();
                    LogUtils.file("Camera1TextureView", "----------------------------------onSurfaceTextureAvailable   startPreview");
                } catch (Exception e) {
                    LogUtils.file("Camera1TextureView", "----------------------------------onSurfaceTextureAvailable   exception=" + e.toString());
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            LogUtils.file("Camera1TextureView", "----------------------------------onSurfaceTextureDestroyed------------------------------------===================");
            stopPreview();
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {

        }
    };

    /**
     * 摄像头回调数据复用内存
     */
    private byte[] cameraCallBackBuffer;
    private int bufferCameraCallbackSize;
    Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            if (null == data) {
                cameraCallBackBuffer = new byte[bufferCameraCallbackSize];
                camera.addCallbackBuffer(cameraCallBackBuffer);
            } else {
                camera.addCallbackBuffer(data);
            }
            if (null != cameraCallBack) {
                cameraCallBack.onPreviewFrameCallBack(data, previewWidth, previewHeight, orientation);
            }
        }
    };

    /**
     * 配置回调接口{@link CameraCallBack#cameraStatus(boolean, String)}
     *
     * @param msg 描述
     */
    private void setCameraStatusFalse(String msg) {
        if (null != cameraCallBack) {
            cameraCallBack.cameraStatus(false, "cameraId:" + cameraID + "   " + msg);
        }
    }

}